"""
进度栏组件。
"""
import typing
from ..framework import dispatch, session_received
from ..base import BaseSession, BaseSessionType, BaseSessionParentType
from .base import BaseWidget
from ..utils import callback, to_any, Int32Value


@session_received
class WidgetProgressBar(BaseSession, BaseWidget):
    """
    进度栏小部件类。
    """
    name = 'WidgetProgressBar'

    @classmethod
    async def create(
            cls: typing.Type[BaseSessionType], parent: BaseSessionParentType, *args: typing.Any, **kwargs: typing.Dict
    ) -> BaseSessionType:
        return await super().create(parent, *cls.parse_region(*args), **kwargs)

    async def on_receive(self, msg):
        """
        组件的事件转发。
        """
        name, sid, fid, argv = msg.name, msg.session, msg.future, msg.argv
        match name:
            case 'onGetRange':
                dispatch(self.on_get_range(*argv, session_id=sid, future_id=fid))
            case 'onGetValue':
                dispatch(self.on_get_value(*argv, session_id=sid, future_id=fis))
            case _:
                dispatch(super().on_widget_action(*argv, name=name, session_id=sid, future_id=fid))

    @callback(int, int)
    async def on_get_range(self, val_min, val_max, session_id=0, future_id=0):
        """
        当获取进度栏值的范围成功后，此方法被自动调用。
        通常不需要关注此方法的实现。
        """
        if not session_id:
            return
        self.set_action_result(session_id, future_id, (val_min, val_max,))

    async def get_range(self) -> tuple[int, int]:
        """
        获取进度栏值的范围。
        调用示例：
        print(await progress_bar.get_range())
        """
        return await self.send_action_until_return('getRange')

    async def set_range(self, val_min: int, val_max: int):
        """
        给进度栏设置值的范围。
        :param val_max: 最大值。
        :param val_min: 最小值。
        调用示例：
        await progress_bar.set_range(0, 100)
        """
        dispatch(self.send_action('setRange', to_any(val_min, Int32Value), to_any(val_max, Int32Value)))

    @callback(int)
    async def on_get_value(self, value, session_id=0, future_id=0):
        """
        当获取进度栏的值成功后，此方法被自动调用。
        通常不需要关注此方法的实现。
        """
        if not session_id:
            return
        self.set_action_result(session_id, future_id, value)

    async def get_value(self) -> int:
        """
        获取进度栏的值。
        调用示例：
        print(await progress_bar.get_value())
        """
        return await self.send_action_until_return('getValue')

    async def set_value(self, value: int):
        """
        给进度栏设置值。
        :param value: 进度栏值。
        调用示例：
        await editor.set_value(50)
        """
        dispatch(self.send_action('setValue', to_any(value)))
